﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;

namespace GBricks.Collections
{
  [ContractClass(typeof(IReadOnlyOrderedDictionaryContract<,>))]
  public interface IReadOnlyOrderedDictionary<TKey, TValue> : IReadOnlyDictionary<TKey, TValue>, IReadOnlyList<KeyValuePair<TKey, TValue>>
  {
    new IReadOnlyList<TKey> Keys { get; }
    new IReadOnlyList<TValue> Values { get; }

    int IndexOf(TKey key);
  }

  [ContractClassFor(typeof(IReadOnlyOrderedDictionary<,>))]
  internal abstract class IReadOnlyOrderedDictionaryContract<TKey, TValue> : IReadOnlyOrderedDictionary<TKey, TValue>
  {
    #region IReadOnlyOrderedDictionary<TKey, TValue> Members

    IReadOnlyList<TKey> IReadOnlyOrderedDictionary<TKey, TValue>.Keys {
      get {
        Contract.Ensures(Contract.Result<IReadOnlyList<TKey>>() != null);
        Contract.Ensures(Contract.Result<IReadOnlyList<TKey>>().Count == Count);
        throw new NotImplementedException();
      }
    }

    IReadOnlyList<TValue> IReadOnlyOrderedDictionary<TKey, TValue>.Values {
      get {
        Contract.Ensures(Contract.Result<IReadOnlyList<TValue>>() != null);
        Contract.Ensures(Contract.Result<IReadOnlyList<TValue>>().Count == Count);
        throw new NotImplementedException();
      }
    }

    [Pure]
    int IReadOnlyOrderedDictionary<TKey, TValue>.IndexOf(TKey key) {
      Contract.Ensures(Contract.Result<int>() >= -1);
      Contract.Ensures(Contract.Result<int>() < Count);
      throw new NotImplementedException();
    }

    #endregion IReadOnlyOrderedDictionary<TKey, TValue> Members

    #region IReadOnlyList<KeyValuePair<TKey, TValue>> Members

    KeyValuePair<TKey, TValue> IReadOnlyList<KeyValuePair<TKey, TValue>>.this[int index] {
      get { return default(KeyValuePair<TKey, TValue>); }
    }

    #endregion IReadOnlyList<KeyValuePair<TKey, TValue>> Members

    #region IReadOnlyDictionary<TKey, TValue> Members

    IEnumerable<TKey> IReadOnlyDictionary<TKey, TValue>.Keys {
      get { throw new NotImplementedException(); }
    }

    IEnumerable<TValue> IReadOnlyDictionary<TKey, TValue>.Values {
      get { throw new NotImplementedException(); }
    }

    TValue IReadOnlyDictionary<TKey, TValue>.this[TKey key] {
      get { throw new NotImplementedException(); }
    }

    public bool ContainsKey(TKey key) {
      throw new NotImplementedException();
    }

    public bool TryGetValue(TKey key, out TValue value) {
      throw new NotImplementedException();
    }

    #endregion IReadOnlyDictionary<TKey, TValue> Members

    #region IReadOnlyCollection<KeyValuePair<TKey,TValue>> Members

    public int Count {
      get { throw new NotImplementedException(); }
    }

    #endregion ICollection<KeyValuePair<TKey, TValue>> Members

    #region IEnumerable<KeyValuePair<TKey, TValue>> Members

    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() {
      throw new NotImplementedException();
    }

    #endregion IEnumerable<KeyValuePair<TKey, TValue>> Members

    #region IEnumerable Members

    IEnumerator IEnumerable.GetEnumerator() {
      throw new NotImplementedException();
    }

    #endregion IEnumerable Members
  }
}
